package com.bitk.config;


import com.bitk.model.Menu;
import com.bitk.model.Role;
import com.bitk.service.MenuService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;

import java.util.Collection;
import java.util.List;

/**
 * 根据用户的请求地址，分析出需要的角色
 */
@Component
public class CustomFilterInvocationSecurityMetadataSource implements FilterInvocationSecurityMetadataSource {

    @Autowired
    MenuService menuService;

    //URL路径匹配工具--spring security自带
    AntPathMatcher antPathMatcher = new AntPathMatcher();

    /**
     * 1.根据用户的请求地址,分析出来他所需要具有的权限
     * @param object 因为是基于过滤器，所有object是FilterInvocation类型的。
     * @return 用户访问的URL所需的权限[Role]
     * @throws IllegalArgumentException
     */
    @Override
    public Collection<ConfigAttribute> getAttributes(Object object) throws IllegalArgumentException {
        //拿到当前请求的地址
        String requestUrl = ((FilterInvocation) object).getRequestUrl();
        System.err.println("---用户请求URL为---"+requestUrl);
        //拿到角色和菜单项的(1:m)查询结果
        List<Menu> menus = menuService.getAllMenusWithRole();
        //进行url路径匹配
        for (Menu menu : menus) {
            //根据访问路径找出所需要的权限
            //用户访问的url如果跟当前menu路径规则匹配成功了，[那就是要访问这个路径]
            //然后我们查查访问这个路径所需要的role
            // 拿到访问该路径所需要的ROLE
            List<Role> roles = menu.getRoles();
            if(antPathMatcher.match(menu.getUrl(),requestUrl)){
                //路径匹配成功
                String[] needRoles = new String[roles.size()];
                for (int i = 0; i < roles.size(); i++) {
                    needRoles[i] = roles.get(i).getName();
                    System.err.println("---访问["+requestUrl+"]需要的权限为---"+needRoles[i]);
                }
                return SecurityConfig.createList(needRoles);
            }
        }
        System.err.println("---用户请求路径["+requestUrl+"]没有匹配上---");
        //没匹配上的路径,怎么处理?==>登录后访问吧
        //这里的参数只是一个标记,会在下一步的流程中处理
        return SecurityConfig.createList("ROLE_LOGIN");
    }

    /**
     * 返回所有定义好的权限资源
     * Spring Security在启动时会校验相关配置是否正确，如果不需要校验，直接返回null
    **/
    @Override
    public Collection<ConfigAttribute> getAllConfigAttributes() {
        return null;
    }

    /**
     * 是否支持校验
     */
    @Override
    public boolean supports(Class<?> clazz) {
        return false;
    }
}
